module ecs {
    /** 
     * 最基本的系统。
     * 在调用world.process()时，系统按顺序处理。
     * 
     * 顺序：
     * {@link #initialize()}——在依赖注入之上初始化您的系统。
     * {@link #begin()}——在处理实体之前调用。
     * {@link #processSystem()}——每循环调用一次。
     * {@link #end()}——在处理实体之后调用。
     */
    export abstract class BaseSystem {
        /** 这个系统所属的世界 */
        protected _world: World;

        constructor() { }

        /**
         * 设置这个系统工作的世界。
         * @param world 
         */
        public setWorld(world: World){
            this._world = world;
        }

        /** 
         * 在系统处理开始之前调用。
         * 在此方法中创建的任何实体都将在下一个系统开始处理或新处理轮开始时(无论哪个先开始)才会激活。
         */
        protected begin() { }

        /**
         * 处理系统
         * 
         * 如果{@link #checkProcessing()}为false或系统已禁用，则不执行任何操作。
         */
        public process() {
            if (this.checkProcessing()) {
                this.begin();
                this.processSystem();
                this.end();
            }
        }

        /**
         * 处理系统
         */
        protected abstract processSystem();

        /**
         * 系统完成处理后调用。
         */
        protected end() { }

        /**
         * 系统是否需要处理。
         * 
         * 在启用系统时非常有用，但只是偶尔需要处理。
         * 
         * 这只影响处理，而不影响事件或订阅列表。
         */
        protected checkProcessing(): boolean {
            return true;
        }

        /** 
         * 重写以实现在初始化系统时执行的代码。
         * 
         * 注意，像系统、工厂和组件映射器这样的本地类型是自动注入的。
         */
        public initialize() { }

        /**
         * {@link World#dispose()}
         */
        public dispose() { }
    }
}
